package displayboardinfo.services;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.xml.bind.JAXBElement;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import com.sun.jersey.api.client.ClientResponse.Status;

import displayboardinfo.entities.User;

/**
 * Klasa odpowiedzialna za wystawianie usług związanych z obsługą użytkowników.
 * 
 * @author Artur Jaworski
 */
@Path("/users")
public class UsersServices {
	
	/**
	 * Usługa dodania nowego użytkownika do bazy.
	 * Usługa dostępna jest na serwerze pod adresem /users/add używając metody POST.
	 * Usługa zwraca kod 200 [OK] gdy wywołanie się powiedzie lub kod 406 [NOT ACCEPTABLE] gdy wystąpi błąd (drugi użytkownik o tym samym loginie, błąd serwera).
	 * Przy wystąpieniu błędu do odpowiedzi dołączany jest krótki opis przyczyny błędu.
	 * 
	 * @param userJaxb obiekt reprezentujący użytkownika dodawanego do systemu, w formie koperty XML
	 * @return obiekt stworzonego użytkownika z uzupełnionym ID nadanym przez bazę danych
	 */
	@SuppressWarnings("deprecation")
	@Path("/add")
	@POST
	@Consumes(MediaType.APPLICATION_XML)
	public User usersAdd(JAXBElement<User> userJaxb) {
		User user = userJaxb.getValue();
		
		SessionFactory sf = new Configuration().configure().buildSessionFactory();
		Session session = sf.openSession();
		Transaction transaction = session.beginTransaction();
		try {
			session.save(user);
			transaction.commit();
			return user;
		} catch (Exception e) {
			transaction.rollback();
			throw new WebApplicationException(Response.status(Status.NOT_ACCEPTABLE).entity("Nieznany błąd").type(MediaType.TEXT_PLAIN).build());
		} finally {
			session.close();
			sf.close();
		}
	}
	
	/**
	 * Usługa modyfikacji istniejącego użytkownika.
	 * Usługa dostępna jest na serwerze pod adresem /users/modify używając metody POST.
	 * Usługa zwraca kod 200 [OK] gdy wywołanie się powiedzie lub kod 406 [NOT ACCEPTABLE] gdy wystąpi błąd (drugi użytkownik o tym samym loginie, błąd serwera).
	 * Przy wystąpieniu błędu do odpowiedzi dołączany jest krótki opis przyczyny błędu.
	 * 
	 * @param userJaxb obiekt reprezentujący modyfikowanego użytkownika, w formie koperty XML
	 * @return obiekt zmodyfikowanego użytkownika
	 */
	@SuppressWarnings("deprecation")
	@Path("/modify")
	@POST
	@Consumes(MediaType.APPLICATION_XML)
	public Response usersModify(JAXBElement<User> userJaxb) {
		User user = userJaxb.getValue();
		
		SessionFactory sf = new Configuration().configure().buildSessionFactory();
		Session session = sf.openSession();
		Transaction transaction = session.beginTransaction();
		try {
			session.update(user);
			transaction.commit();
			return Response.ok().build();
		} catch (Exception e) {
			transaction.rollback();
			throw new WebApplicationException(Response.status(Status.NOT_ACCEPTABLE).entity("Nieznany błąd").type(MediaType.TEXT_PLAIN).build());
		} finally {
			session.close();
			sf.close();
		}

	}
	
	/**
	 * Usługa usunięcia istniejącego użytkownika.
	 * Usługa dostępna jest na serwerze pod adresem /users/delete używając metody POST.
	 * Usługa zwraca kod 200 [OK] gdy wywołanie się powiedzie lub kod 406 [NOT ACCEPTABLE] gdy wystąpi błąd (nieistniejący użytkownik, błąd serwera).
	 * Przy wystąpieniu błędu do odpowiedzi dołączany jest krótki opis przyczyny błędu.
	 * 
	 * @param userJaxb obiekt reprezentujący użytkownika usuwanego z systemu, w formie koperty XML
	 * @return pusta odpowiedź, zawierająca kod i komunikat o błędzie w przypadku niepowodzenia
	 */
	@SuppressWarnings("deprecation")
	@Path("/delete")
	@POST
	@Consumes(MediaType.APPLICATION_XML)
	public Response usersDelete(JAXBElement<User> userJaxb) {
		User user = userJaxb.getValue();

		SessionFactory sf = new Configuration().configure().buildSessionFactory();
		Session session = sf.openSession();
		Transaction transaction = session.beginTransaction();
		try {
			session.delete(user);
			transaction.commit();
			return Response.ok().build();
		} catch (Exception e) {
			transaction.rollback();
			throw new WebApplicationException(Response.status(Status.NOT_ACCEPTABLE).entity("Nieznany błąd").type(MediaType.TEXT_PLAIN).build());
		} finally {
			session.close();
			sf.close();
		}

	}
}
